﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web.Mvc.Html;

namespace System.Web.Mvc
{
    public static class ListViewBuilder
    {
        public static MvcHtmlString CreateListView<TModel>(this HtmlHelper<IEnumerable<TModel>> htmlHelper, string[] columns = null)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendFormat("<table class=\"datatable\">{0}{1}</table>", 
                generateHeader<TModel>(columns), 
                generateBody<TModel>(htmlHelper, columns));

            return MvcHtmlString.Create(builder.ToString());
        }

        private static StringBuilder generateHeader<TModel>(string[] columns)
        {
            StringBuilder headerBuilder = new StringBuilder();
            headerBuilder.Append("<tr>");
            foreach (var pInfo in typeof(TModel).GetProperties())
            {
                var descriptionAttribute = (DescriptionAttribute)pInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault();
                var title = descriptionAttribute != null ? descriptionAttribute.Description : pInfo.Name;

                //Add the columns
                if (columns != null)
                {
                    if (columns.Contains(pInfo.Name))
                        headerBuilder.AppendFormat("<th>{0}</th>", title);
                }
                else headerBuilder.AppendFormat("<th>{0}</th>", title);
            }

            //Add the command button column
            headerBuilder.Append("<th></th>");
            headerBuilder.Append("</tr>");
            return headerBuilder;
        }

        private static StringBuilder generateBody<TModel>(HtmlHelper<IEnumerable<TModel>> htmlHelper, string[] columns)
        {
            StringBuilder bodyBuilder = new StringBuilder();

            var idProperty = typeof(TModel).GetProperty("Id");

            foreach (var item in htmlHelper.ViewData.Model)
            {
                bodyBuilder.Append("<tr>");
                foreach (var pInfo in typeof(TModel).GetProperties())
                {
                    if (columns != null)
                    {
                        if (columns.Contains(pInfo.Name))
                            bodyBuilder.AppendFormat("<td>{0}</td>", pInfo.GetValue(item, null));
                    }
                    else bodyBuilder.AppendFormat("<td>{0}</td>", pInfo.GetValue(item, null));
                }

                bodyBuilder.AppendFormat("<td>{0}|{1}|{2}</td>",
                        htmlHelper.ActionLink("Edit", "Edit", new { Id = idProperty.GetValue(item, null) }),
                        htmlHelper.ActionLink("Details", "Details", new { Id = idProperty.GetValue(item, null) }),
                        htmlHelper.ActionLink("Delete", "Delete", new { Id = idProperty.GetValue(item, null) }));

                bodyBuilder.Append("</tr>");
            }

            return bodyBuilder;
        }
    }
}
